import commands
import os
import shutil
import time

from ToolMtkSecurityPatch import get_patch_from_code, find_real_git_path, handle_patch_file
from common.ToolsExcel import add_to_sheet, create_excel, create_sheet, save_excel

# ######################################CONFIG begin
CONFIG_SRC_CODE_PATH = '/home/android/Platform/mtk'

# CONFIG_DST_CODE_PATH = '/home/android/Platform/Platform_p130_2/android'
CONFIG_DST_CODE_PATH = '/home/android/Platform/6739O/android'

CONFIG_PATCH_SAVE_PATH = '/home/android/Opensource/WorkSpace_Py/Mtk_Patch'

CONFIG_OLD_BRANCH_NAME = 'remotes/tinno/ALPS-RELEASE-O1.MP1-V1.54-READONLY'
CONFIG_NEW_BRANCH_NAME = 'remotes/tinno/ALPS-RELEASE-O1.MP1-V1.69-READONLY'

CONFIG_REPO_PREFIX = ''

CONFIG_JIRA_ID = 'PCAAO-1924'


# ######################################CONFIG end


def is_set(v):
    try:
        type(eval(v))
    except:
        return 0
    else:
        return 1


def get_commit_log_by_base_line(src_code_path, save_path, old_branch, new_branch):
    commit_log_path = os.path.join(save_path, 'all_commit_log')
    if os.path.isfile(commit_log_path):
        return 1, commit_log_path
    if os.path.isdir(save_path):
        shutil.rmtree(save_path)
    os.makedirs(save_path)
    os.chdir(src_code_path)
    cmd = 'repo forall -p -c git log %s..%s > %s' % (old_branch, new_branch, commit_log_path)
    ret = os.system(cmd)
    return ret, commit_log_path


def handle_patch(repo_name, commit, save_path, cur_num, sheet):
    ret, dst_patch_path = get_patch_from_code(CONFIG_SRC_CODE_PATH, repo_name, commit, save_path)
    fix_repo_name = repo_name[len(CONFIG_REPO_PREFIX):]
    if ret is not 0:
        print("\033[43;31;1mget_patch_from_code error ret=%s fix_repo_name=%s\033[0m" % (
            ret, fix_repo_name))
        info = [cur_num, '', commit, repo_name, fix_repo_name, '', '', '', 'Failed',
                'Get mtk patch failed']
        add_to_sheet(sheet, info, cur_num + 1)
        result = -1
    else:
        dst_git_path = find_real_git_path(CONFIG_DST_CODE_PATH, fix_repo_name)
        if dst_git_path is None:
            info = [cur_num, '', commit, repo_name, fix_repo_name, '', '', '', 'Failed',
                    'Get tinno git failed']
            add_to_sheet(sheet, info, cur_num + 1)
            print("Cannot find tinno git")
            result = -2
        else:
            dst_repo_name = dst_git_path[len(CONFIG_DST_CODE_PATH) + 1:]
            subject_title, diff_info = handle_patch_file(dst_git_path, dst_patch_path, fix_repo_name, dst_repo_name)
            if subject_title is '':
                info = [cur_num, subject_title, commit, repo_name, fix_repo_name, '',
                        dst_patch_path[len(save_path):] + "bk", dst_repo_name, 'Failed', diff_info,
                        'Handle patch file failed']
                add_to_sheet(sheet, info, cur_num + 1)
                print('handle_patch_file error dst_git_path=%s dst_patch_path=%s' % (dst_git_path, dst_patch_path))
                return -5

            os_cmd_apply = "cd %s; git apply --whitespace=fix %s" % (dst_git_path, dst_patch_path + "bk")

            print("apply cmd", os_cmd_apply)
            print("dst_git_path", dst_git_path)
            print("dst_patch_path", dst_patch_path + "bk")
            print("subject_title", subject_title)
            print("jira id", CONFIG_JIRA_ID)

            apply_status, apply_info = commands.getstatusoutput(os_cmd_apply)
            if apply_status != 0:
                print("\033[43;31;1mapply failed error apply_status=%s info=%s\033[0m" % (
                    apply_status, apply_info))
                info = [cur_num, subject_title, commit, repo_name, fix_repo_name, '',
                        dst_patch_path[len(save_path):] + "bk", dst_repo_name, 'Failed', diff_info,
                        apply_info]
                add_to_sheet(sheet, info, cur_num + 1)
                result = -3
            else:
                commit_str = "\'<REQ><%s><%s>\'" % (CONFIG_JIRA_ID, subject_title[len("Subject: "):])
                os_cmd_commit = "cd %s; git add -A .; git commit -m %s" % (dst_git_path, commit_str)
                print("os_cmd_commit=" + os_cmd_commit)
                commit_status, commit_info = commands.getstatusoutput(os_cmd_commit)
                if commit_status == 0:
                    log_status, git_log = commands.getstatusoutput(
                        'cd %s; git log | grep -m1 "commit "' % dst_git_path)
                    info = [cur_num, subject_title, commit, repo_name, fix_repo_name,
                            git_log.strip()[7:],
                            dst_patch_path[len(save_path):] + "bk", dst_repo_name, 'Success', 'ok']
                    add_to_sheet(sheet, info, cur_num + 1)
                    result = 0
                else:
                    info = [cur_num, subject_title, commit, repo_name, fix_repo_name, '',
                            dst_patch_path[len(save_path):] + "bk", dst_repo_name, 'Failed', diff_info,
                            commit_info]
                    add_to_sheet(sheet, info, cur_num + 1)

                    print("\033[43;31;1mcommit failed error commit_status=%s info=%s\033[0m" % (
                        commit_status, commit_info))
                    result = -4
    return result


def parse_commit_log_and_save_patches(commit_log_path, save_path):
    get_patch_failed_count = 0
    find_tinno_patch_failed_count = 0
    git_apply_failed_count = 0
    git_commit_failed_count = 0
    handle_patch_file_error_count = 0

    success_count = 0

    total_commit_num = 0
    with open(commit_log_path) as f:
        for line in f:
            line = line.strip()
            if line.startswith('commit '):
                total_commit_num = total_commit_num + 1
        f.close()

    workbook = create_excel()
    sheet = create_sheet(workbook, 'patch_info', True)

    first_row = ['No', 'title', 'mtk_commit_id', 'mtk_git', 'fix_mtk_git', 'tinno_commit_id', 'patch_path', 'tinno_git',
                 'result', 'info', 'diff_info', 'git_error_log']
    add_to_sheet(sheet, first_row, 1)

    cur_num = 0
    with open(commit_log_path) as f:
        sub_commit_list = []
        for line in f:
            line = line.strip()
            if line.startswith('project ') and line[-1] is '/':  # project bionic/
                sub_commit_list.reverse()
                for commit in sub_commit_list:
                    cur_num = cur_num + 1
                    print("[%s/%s]+++++++++++++++++++++++++++++++++++++++++%s" % (cur_num, total_commit_num, repo_name))
                    ret = handle_patch(repo_name, commit, save_path, cur_num, sheet)
                    if ret == 0:
                        success_count = success_count + 1
                    elif ret == -1:
                        get_patch_failed_count = get_patch_failed_count + 1
                    elif ret == -2:
                        find_tinno_patch_failed_count = find_tinno_patch_failed_count + 1
                    elif ret == -3:
                        git_apply_failed_count = git_apply_failed_count + 1
                    elif ret == -4:
                        git_commit_failed_count = git_commit_failed_count + 1
                    elif ret == -5:
                        handle_patch_file_error_count = handle_patch_file_error_count + 1
                    print("[%s/%s]------------------------------------------\n" % (cur_num, total_commit_num))
                repo_name = line[8:]
                sub_commit_list = []
            elif line.startswith('commit '):
                commit = line[7:]
                sub_commit_list.append(commit)
                if not is_set(repo_name):
                    assert 1

        sub_commit_list.reverse()
        for commit in sub_commit_list:
            cur_num = cur_num + 1
            print("[%s/%s]+++++++++++++++++++++++++++++++++++++++++%s" % (cur_num, total_commit_num, repo_name))
            ret = handle_patch(repo_name, commit, save_path, cur_num, sheet)
            if ret == 0:
                success_count = success_count + 1
            elif ret == -1:
                get_patch_failed_count = get_patch_failed_count + 1
            elif ret == -2:
                find_tinno_patch_failed_count = find_tinno_patch_failed_count + 1
            elif ret == -3:
                git_apply_failed_count = git_apply_failed_count + 1
            elif ret == -4:
                git_commit_failed_count = git_commit_failed_count + 1
            elif ret == -5:
                handle_patch_file_error_count = handle_patch_file_error_count + 1
            print("[%s/%s]------------------------------------------\n" % (cur_num, total_commit_num))
        f.close()

    print("**********************************************************")
    total_failed = get_patch_failed_count + find_tinno_patch_failed_count + git_apply_failed_count + \
                   git_commit_failed_count + handle_patch_file_error_count
    print("total=%s failed=%s success=%s" % (cur_num, total_failed, success_count))
    print("get_patch_failed_count=%s" % get_patch_failed_count)
    print("find_tinno_patch_failed_count=%s" % find_tinno_patch_failed_count)
    print("git_apply_failed_count=%s" % git_apply_failed_count)
    print("git_commit_failed_count=%s" % git_commit_failed_count)
    print("handle_patch_file_error_count=%s" % handle_patch_file_error_count)
    print("**********************************************************")

    patch_time = time.strftime('%Y-%m-%d_%H-%M-%S', time.localtime(time.time()))

    info_num = cur_num + 5

    add_to_sheet(sheet, ['', 'Patch Time: %s' % patch_time], info_num)
    info_num = info_num + 1
    add_to_sheet(sheet, ['', 'old branch: %s' % CONFIG_OLD_BRANCH_NAME], info_num)
    info_num = info_num + 1
    add_to_sheet(sheet, ['', 'new branch: %s' % CONFIG_NEW_BRANCH_NAME], info_num)
    info_num = info_num + 1
    add_to_sheet(sheet, ['', 'patch result[SUCCESS:%s FAILED:%s TOTAL:%s]' % (
        success_count, total_failed, cur_num)], info_num)

    info_num = info_num + 5
    add_to_sheet(sheet, ['', 'get_patch_failed_count: %s' % get_patch_failed_count], info_num)
    info_num = info_num + 1
    add_to_sheet(sheet, ['', 'find_tinno_patch_failed_count: %s' % find_tinno_patch_failed_count], info_num)
    info_num = info_num + 1
    add_to_sheet(sheet, ['', 'git_apply_failed_count: %s' % git_apply_failed_count], info_num)
    info_num = info_num + 1
    add_to_sheet(sheet, ['', 'git_commit_failed_count: %s' % git_commit_failed_count], info_num)
    info_num = info_num + 1
    add_to_sheet(sheet, ['', 'handle_patch_file_error_count: %s' % handle_patch_file_error_count], info_num)
    info_num = info_num + 1
    add_to_sheet(sheet, ['', 'CONFIG_SRC_CODE_PATH: %s' % CONFIG_SRC_CODE_PATH], info_num)
    info_num = info_num + 1
    add_to_sheet(sheet, ['', 'CONFIG_DST_CODE_PATH: %s' % CONFIG_DST_CODE_PATH], info_num)
    info_num = info_num + 1
    add_to_sheet(sheet, ['', 'CONFIG_PATCH_SAVE_PATH: %s' % CONFIG_PATCH_SAVE_PATH], info_num)

    save_excel(workbook, os.path.join(CONFIG_PATCH_SAVE_PATH, patch_time + '.xlsx'))


if __name__ == '__main__':
    print('get all patch info ...')
    _ret, _commit_log = get_commit_log_by_base_line(CONFIG_SRC_CODE_PATH, CONFIG_PATCH_SAVE_PATH,
                                                    CONFIG_OLD_BRANCH_NAME, CONFIG_NEW_BRANCH_NAME)
    print('get all patch info done _ret=%s _commit_log=%s' % (_ret, _commit_log))
    if _ret >= 0:
        parse_commit_log_and_save_patches(_commit_log, CONFIG_PATCH_SAVE_PATH)
